/**
 * @file penguin_fsm.h
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2022-08-03
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#ifndef PENGUIN_FSM_H_
#define PENGUIN_FSM_H_

#define HFSM2_ENABLE_LOG_INTERFACE
#define HFSM2_ENABLE_STRUCTURE_REPORT

#include "hfsm2/machine.hpp"
#include <iostream>

class Penguin;

/*************** 定义事件 ***************/

// 日出
struct Sunrise{};

// 日落
struct Sunset{};

// 豆豆
struct Doudou{};

/**************** 定义事件 ***************/

using M = hfsm2::MachineT<hfsm2::Config::ContextT<Penguin*>>;

#define S(s) struct s
using FSM = M::PeerRoot<S(Eatting), S(Sleep), S(BeatDoudou)>;
#undef S

struct Base : FSM::State {
  template <typename TEvent>
  void react(const TEvent&, FullControl&) noexcept {
    std::cout << "nothing happend" << std::endl;
  }
};

struct Eatting:Base{
    using Base::react;
    void react(const Doudou&, FullControl& f) noexcept; // NOLINT
};

struct Sleep: Base
{
    using Base::react;
    void react(const Sunrise&, FullControl& f) noexcept; // NOLINT
};

struct BeatDoudou: Base
{
    using Base::react;
    void react(const Sunset&, FullControl& f) noexcept; // NOLINT
};



// 状态变化记录
struct FSM_Logger:M::LoggerInterface{
  static const char* stateName(const StateID stateId) noexcept {
    switch (stateId) {
      case 1:
        return "Eatting";
      case 2:
        return "Sleep";
      case 3:
        return "BeatDoudou";
      default:
        return "###################";
    }
  }

  void recordTransition(Context& ctx, const StateID origin,
                        const TransitionType,
                        const StateID target) noexcept override;
};

#endif  // PENGUIN_FSM_H_
